﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufExtension.h"
#include <GnufIProjectDisplay.h>
#include <GnufNotificationCenterEventArgs.h>
#include "GnufNotificationCenter.h"

namespace gcmp {
    class IUiView;
    class IUiDocument;
    class IDocument;
    class IUiViewEventArgs;
}

namespace gnuf {
    
    class GnufDisplayManager;
    class GnufModelDisplay;
    class GnufAssetDisplay;
    class GnufProjectDisplayImpl;
    
    class GNUF_EXTENSION_EXPORT GnufProjectDisplay final : public IProjectDisplay
    {
        DEFINE_CAST_DERIVED(GnufProjectDisplay,gnuf::IProjectDisplay)

    public:
        static gcmp::OwnerPtr< GnufProjectDisplay > make(GnufDisplayManager *, const gcmp::IUiDocument *);
        virtual ~GnufProjectDisplay();

        GnufDisplayManager * holder() const { return m_holder; }

        int uiDocumentId() const { return m_uiDocId; }
        gcmp::IUiDocument * uiDocument() const;

        void updateCaption(const gcmp::IUiDocument *, bool wantToNotify);
        const std::wstring & caption() const { return m_caption; }

        void updateBackground();
        
        bool isActive() const { return m_active; }
        
        bool isClosing() const { return m_closing; }
        bool isActivating() const { return m_activating; }
        bool isDeactivating() const { return m_deactivating; }
        
        const GnufAssetDisplay * activeAssetDisplay() const;
        GnufAssetDisplay * activeAssetDisplay() ;

        typedef typename std::list< gcmp::OwnerPtr< GnufAssetDisplay > > AssetDisplays;
        typedef typename std::vector< GnufAssetDisplay * > RawAssetDisplays;
        const GnufProjectDisplay::AssetDisplays & assetDisplays() const;
        GnufProjectDisplay::RawAssetDisplays rawAssetDisplays();

        const GnufAssetDisplay * assetDisplayById(const std::string &) const;
        GnufAssetDisplay * assetDisplayById(const std::string &) ;
        
        // Return true if the Gcmp UiDocument has only one UiView.
        // Return false, otherwise.
        bool hasOnlyOneUiView() const;
        
        // Return true if the Gcmp UiDocument has no any UiView.
        // Return false, otherwise.
        bool hasNoUiView() const;
        
        // Return true if the Gcmp UiDocument allows to close.
        // Return false, otherwise.
        bool allowToCloseUiDocument() const;

        bool isClosingAssetDisplay() const;

        void onPostClosed(const GnufAssetDisplay * const);
        void onPostActivated(const GnufAssetDisplay * const);

        void setAtTheTop(const GnufAssetDisplay * const);

        void delayToHandleCreatingFirstUiViewUntilActivated(gcmp::IUiView *);

        void setWorking(bool);
        bool isWorking() const { return m_working; }
        
    protected:
        // Inherits from IProjectDisplay...
        virtual IDisplayManager * onGetDisplayManager() const override;
        virtual void onClose() override;
        virtual void onActivate() override;
        virtual void onDeactivate() override;
        virtual bool onIsActive() const { return m_active; }
        virtual void onSetTabIds(const std::vector<std::string> & ids) override 
        { m_tabIds = ids; }
        virtual const std::vector<std::string> & onGetTabIds() const override
        { return m_tabIds; }
        virtual size_t onGetNumberOfAssetDisplays() const override;
        virtual IAssetDisplay * onGetAssetDisplayById(const std::string &) override;
        virtual IAssetDisplay * onGetActiveAssetDisplay() override;
        virtual std::list< IAssetDisplay *> onGetAllAssetDisplays()  override;
        virtual const std::wstring & onGetCaption() const
        { return m_caption; }

        void On(gcmp::IUiViewEventArgs *);

    private:
        friend class GnufAssetDisplay;
        GnufAssetDisplay * add(gcmp::OwnerPtr<GnufAssetDisplay> &&);
        gcmp::OwnerPtr<GnufAssetDisplay> remove(const GnufAssetDisplay * const);
    
        friend class GnufDisplayManager;
        bool onDoClose();
        bool onDoActivate();
        bool onDoDeactivate();
        void endCreating();
        void endClosing();
        void endActivating();
        void endDeactivating();

        void notify(ProjectDisplayEventArgs::EType, ENotificationChannel channel = ENotificationChannel::eInput);
        void setCaption(const gcmp::IUiDocument *, bool);
        void closeAllAssetDisplays();
        void handleCreating(gcmp::OwnerPtr<GnufModelDisplay> &&, gcmp::IUiView *);
    
        explicit GnufProjectDisplay(GnufDisplayManager *, const gcmp::IUiDocument *);

        bool m_working;
        GnufDisplayManager * m_holder;
        const int m_uiDocId;
        std::wstring m_caption;
        bool m_active;
        bool m_closing;
        bool m_activating;
        bool m_deactivating;
        gcmp::WeakPtr<gcmp::IUiView> m_delayToHandleCreatingFirstUiViewUntilActivated;
        std::vector<std::string> m_tabIds;
        gcmp::OwnerPtr<GnufProjectDisplayImpl> m_impl;
    };
}
